﻿using System.ComponentModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq.Expressions;
using System.Reflection;
using System.Windows;
using System;
using System.Linq;
using System.Windows.Input;
using Illusion.CM;

namespace Illusion
{
	/// <summary>
	/// A base viewmodel class that implemented <see cref="INotifyPropertyChanged"/>.
	/// </summary>
	[Serializable]
	public abstract class ViewModelBase : INotifyPropertyChanged
	{
		#region Field

		[NonSerialized]
		Dictionary<string, ICommand> _commands = new Dictionary<string, ICommand>();

		#endregion

		#region Property

		/// <summary>
		/// Gets the command.
		/// </summary>
		/// <value>The command.</value>
		[System.Xml.Serialization.XmlIgnoreAttribute]
		public Dictionary<string, ICommand> Command
		{
			get
			{
				return _commands;
			}
		}

		#endregion

		#region INotifyPropertyChanged Members

		/// <summary>
		/// Occurs when a property value changes.
		/// </summary>
		public event PropertyChangedEventHandler PropertyChanged;

		/// <summary>
		/// Notifies the property changed.
		/// </summary>
		/// <param name="propertyName">Name of the property.</param>
		protected void NotifyPropertyChanged(string propertyName)
		{
			PropertyChangedEventHandler handler = PropertyChanged;

			if (handler != null)
			{
				handler(this, new PropertyChangedEventArgs(propertyName));
			}
		}

        /// <summary>
        ///   Notifies subscribers of the property change.
        /// </summary>
        /// <typeparam name = "TProperty">The type of the property.</typeparam>
        /// <param name = "property">The property expression.</param>
        public virtual void NotifyPropertyChanged<TProperty>(Expression<Func<TProperty>> property)
        {
            NotifyPropertyChanged(property.GetMemberInfo().Name);
        }

		#endregion
	}
}
